/* natAlgApi.h */

/* NAT Application Level Gateway (ALG) Application Programming Interface */

/* Copyright 2000-2005 Wind River Systems, Inc. */

/* @format.tab-size 4, @format.use-tabs true, @format.new-line lf */

/*
modification history
--------------------
01b,16feb05,svk  Remove old branding
01a,25apr03,zhu  updated copyright
110403  vks     added NODE element to NAT_BIND_INFO structure
092402  vvv     added include for lstLib.h
092402  vvv     added NODE element to NAT_AGENT_INFO structure
092101  tk		Change the format of natGetTransportBind function.  Add new data types
				NAT_BIND_SESSION and NAT_BIND_CHECK.
082801  zhu     Redefinition of NAT_DIRECTION to match nat snmp.
080701	tk		Add NAT_AGENT_EVENT and NAT_EVENT_INFO structures.
070201	tk		Add more parameters in NAT_BIND_INFO, and add name field in NAT_AGENT_INFO.
				Change parameters in NAT_STATUS.
060401	tk		Add natUnregisterAgent function declaration.
*/

#ifndef __INCnatAlgApih
#define __INCnatAlgApih

#include <vxWorks.h>
#include <lstLib.h>

typedef enum {									/* Valid return value for all AlgApi functions */
	 NAT_OK										/* No error */
	,NAT_INVALID_NAT_ID							/* Invalid NAT instance ID (NULL?) */
	,NAT_INVALID_AGENT_ID						/* Invalid NAT agent id (not registered) */
	,NAT_INVALID_BIND_ID						/* Invalid bind ID */
	,NAT_INVALID_BIND_INFO						/* One or all of the bind params is not valid */
	,NAT_INVALID_SESSION_ID						/* Invalid session ID */
	,NAT_INVALID_SESSION_INFO					/* One or all of the session params is not valid */
	,NAT_INVALID_BUNDLE_ID						/* Invalid bundle ID */
	,NAT_INVALID_ARG_PTR						/* Invalid pointer argument (NULL?) */
	,NAT_BIND_MAKE_FAILED						/* Unable to create BIND or set bind params */
	,NAT_SESSION_MAKE_FAILED					/* Unable to create session or set session params */
	,NAT_BIND_NO_MATCH							/* No bind matching the specified addresses */
	,NAT_UNSUPPORTED_AGENT_TYPE					/* unsupported agent type */
	,NAT_UNSUPPORTED_TUNNEL_TYPE				/* unsupported tunnel type */
	,NAT_UNSUPPORTED_FEATURE					/* unsupported feature */
	,NAT_SYSTEM_ERROR							/* e.g., malloc() failed */
	
} NAT_STATUS;
												/* Valid bits for nat_id_info.type */
#define NAT_TYPE_BASIC				(1<<0)		/* Basic NAT */
#define NAT_TYPE_NAPT				(1<<1)		/* Network Address/Protocol Translator */
#define NAT_TYPE_BI_DIR				(1<<2)		/* Bi-directional */
#define NAT_TYPE_TWICE				(1<<3)		/* Twice-NAT */
#define NAT_TYPE_RSA_IP_SERVER		(1<<4)		/* RSA-IP Server */
#define NAT_TYPE_RSAP_IP_SERVER		(1<<5)		/* RSAP-IP Server */
												/* Used for query operations only */		
#define	NAT_TYPE_ALL				0			/* Report all NAT instances */

#if 0											/* Valid bits for NAT_AGENT_INFO.events */
#define NAT_EVENT_DOWN				(1<<0)		/* NAT terminated */
#define NAT_EVENT_TIMER				(1<<1)		/* NAT timer */
#endif

#define NAT_FLAG_NO_XLAT			(1<<0)		/* NAT does no IP/TCP/UDP translations */
#define NAT_FLAG_PRE_XLAT			(1<<1)		/* Agent gets packet before NAT translations */
#define NAT_FLAG_POST_XLAT			(1<<2)		/* Agent gets packet after NAT translations */

#define NAT_AGENT_DESC_LEN			128			/* Max agent description length (w/terminator) */

#define NAT_AGENT_NAME_LEN			16			/* Max name of agent */

typedef enum {									/* Valid values for NAT_AGENT_INFO.type */
	 NAT_AGENT_TYPE_ALG							/* Application Level Gateway */
	,NAT_AGENT_TYPE_RSIP_CLIENT					/* RSIP client */
	,NAT_AGENT_TYPE_BACKUP_NAT					/* Back-up NAT */
	,NAT_AGENT_TYPE_MGMT_APP					/* Management application */
	,NAT_AGENT_TYPE_LAST						/* Must be last element of enum */

} NAT_AGENT_TYPE;

typedef enum {									/* NAT bind type */
	 NAT_BIND_BASIC   	 						/* Basic (address only) */
	,NAT_BIND_NAPT								/* Address and Transport ID */

} NAT_BIND_TYPE;

typedef enum {									/* NAT bind check */
	NAT_BIND_FULL								/* check both remote address & port */
   ,NAT_BIND_PARTIAL							/* check remote address only */
} NAT_BIND_CHECK;

typedef enum {									/* Valid bits for NAT_AGENT_INFO.events */
	NAT_BIND_CREATION							/* bind creation */
   ,NAT_BIND_TERMINATION						/* bind termination */
   ,NAT_SESSION_CREATION						/* session creation */
   ,NAT_SESSION_TERMINATION						/* session termination */

} NAT_AGENT_EVENT;

typedef enum {									/* NAT session direction */
	 NAT_OUTBOUND = 1							/* outbound (from private realm) */
	,NAT_INBOUND								/* inbound (from public realm) */
	,NAT_BIDIR									/* bi-directional */

} NAT_DIRECTION;


typedef struct {								/* NAT instance information */
	u_long					id;					/* NAT_CLASS instance pointer */
	u_long					type;				/* bit-field of supported NAT_TYPEs */
	BOOL					enabled;			/* transalations enabled/disabled */

} NAT_ID_INFO;

typedef struct {								/* Session tag */
	u_short					protocol;			/* IP protocol (TCP, UDP, ICMP, etc) */
	u_short					transport;			/* Transport ID (TCP/UDP port or ICMP ID) */

} NAT_SESSION_TAG;

typedef struct {							/* Session parameters */
	u_long				src_addr;			/* Source IPv4 address */
	u_short				src_transport;		/* Source transport-id */
	u_long				dest_addr;			/* Destination IPv4 address */
	u_short				dest_transport;		/* Destination transport-id */

} NAT_SESSION_PARMS;

typedef struct {							/* Session parameters */
	u_short				protocol;			/* Session protocol (TCP/UDP) */
	u_long				local_addr;			/* Local IPv4 address */
	u_short				local_transport;	/* Local transport-id */
	u_long				remote_addr;		/* Remote IPv4 address */
	u_short				remote_transport;	/* Remote transport-id */
	u_long				global_addr;		/* Global IPv4 address */
	u_short				global_transport;	/* Global transport-id */

} NAT_BIND_SESSION;

typedef struct {
	NODE				node;	
	u_long				id;					/* Unique identifier for this bind (see note 1 below) */
	u_long				agent_id;			/* Controlling agent (0 = NAT itself) */
	NAT_BIND_TYPE		type;				/* Basic (address only) or NAPT */
	NAT_DIRECTION		direction;			/* Inbound or Outbound direction (see note 2 below) */
	BOOL				static_entry;		/* Does not expire (see note 3 below) */
	BOOL				use_local_port;		/* Use local port as the global port (see note 4 below) */
	u_short				protocol;			/* TCP/UDP */
	u_long				local_addr;			/* Local IPv4 address */
	u_short				local_transport;	/* Local transport-ID (TCP/UDP port) */
	u_long				global_addr;		/* Global IPv4 address */
	u_short				global_transport;	/* Global transport-ID (TCP/UDP port) */
	u_long				remote_addr;		/* Remote (destination) address */
	u_short				remote_transport;	/* Remote (destination) port (see note 5 below) */
	u_long				max_idle_time;		/* max idle time of dynamic bind (see note 6 below) */
	u_long				current_idle_time;	/* current bind's idle time (see note 6 below) */
	u_long				max_lease_time;		/* relevant only to RSIP (see note 6 below) */
	u_long				avail_lease_time;	/* relevant only to RSIP (see note 6 below) */
	u_long				nat_transport_entry;/* NAT TCP/UDP translation entry (see note 7 below) */
	u_long				nat_address_entry;	/* NAT ip translation entry (see note 8 below) */

} NAT_BIND_INFO;

/************************** Note for NAT_BIND_INFO structure ***********************************

1. If this id is set to 0, the caller requests NAT to create a new bind descriptor.  The caller
   is responsible for filling in the parameters defined in the above structure prior to calling
   natSetBind.  Upon successful creation of the bind, natSetBind will fill in the ID of the
   bind in this field.  If the id is set to a non-zero value, the caller requests NAT to set
   some or all parameters in the existing bind.  The latter feature is not supported in the
   current implementation of natSetBind.

2. Typically, the direction is set to OUTBOUND if the address bind is created as a result of
   an outbound traffic.  Conversely, it is set to INBOUND if the bind is created as a result
   of an inbound traffic.  Regardless of the direction, natSetBind will cause NAT to create a
   bind descriptor.  If the direction is OUTBOUND in NAPT, NAT will set the global port in this  
   bind to the local spoofed port unless the use_local_port field is set (see note 3).  For
   INBOUND direction, it is the responsibility of the NAT client to assign the global port 
   number in the bind as this is equivalent to creating a static entry but the duration of
   the bind can be set by the static_entry field (see note 3).

3. When static_entry is set to FALSE, the bind lives only for the duration of its timer.  When
   its timer expires, NAT will automatically deletes the bind.  If it is set to TRUE, the bind
   is kept alive even when its timer expires until it is specifically deleted by calling 
   natFreeBind or by commands from the shell (i.e. natTcpStaticDelete or natUdpStaticDelete).
   The timer may show 0 when it expires in the static bind, but will be reset to its default
   value again when the bind is reactivated (i.e. new packet whose address matches this bind is
   received)

4. When use_local_port is set to TRUE and direction is set to OUTBOUND, the global port in the
   created bind will be set to the source (or local) port instead of the local spoofed port.
   This feature is required in some ALGs (H.323 ALG is an example of this).

5. The remote_transport (or TCP/UDP port of the remote host) field may not be known sometimes
   at the time of the bind creation.  This is particularly true when one creates an OUTBOUND
   bind in preparation of future inbound session (some ALGs may require this).  In such a case,
   the remote_transport can be left unknown when calling natSetBind.  NAT will later assign
   the correct value of the remote_transport when the actual inbound session is started.

6. Field is defined but not supported in the current implementation.

7. nat_transport_entry provides the link between the bind descriptor and the actual TCP/UDP 
   translation entry managed internally by NAT.  The value of this field can be set to 0 
   before calling natSetBind.  When natSetBind is called, a new translation entry is created 
   internally by NAT, and the pointer to this entry is stored in this field.  For historical 
   reason, NAT internally creates and maintains different sets of translation lists apart from 
   the bind list.  Having this field enables NAT to also call natSetBind to create a new 
   translation entry and to correlate between the bind descriptor and the translation entry it 
   has just created.  It may also be useful for the ALG if it wishes to tap into NAT's internal 
   translation entry parameters; otherwise, the ALG may just ignore this field. 

8. nat_address_entry provides the link between the bind descriptor and the actual IP
   translation entry managed internally by NAT.  This field serves the same purpose as the
   nat_transport_entry except it is used only for the IP translation.  This field applies only 
   to Basic NAT.
*************************************************************************************************/

typedef struct {
	u_long					id;					/* Unique identifier for this session */
	u_long					agent_id;			/* Controlling agent (0 = NAT agent) */
	u_long					bundle_id;			/* For ALG use, defaults to session id */
	NAT_DIRECTION			direction;			/* Inbound/Outbound/Bidir */
	u_long					pri_bind_id;		/* Primary bind id */
	u_long					sec_bind_id;		/* Secondary bind id (Twice-NAT) */
	NAT_SESSION_PARMS		org_session;		/* Original session parameters */
	NAT_SESSION_PARMS		xlat_session;		/* Translated session parameters */			
	NAT_SESSION_TAG			session_tag;		/* Identifies type of packets to translate */

} NAT_SESSION_INFO;

typedef struct {
	NAT_BIND_INFO			*bind_info;			/* pointer to bind entry */
	NAT_SESSION_INFO		*session_info;		/* pointer to session entry */

} NAT_EVENT_INFO;

typedef void(*NAT_EVENT_CALLBACK)
	(u_long nat_id, u_long agent_id, NAT_AGENT_EVENT event, NAT_EVENT_INFO *event_info);

typedef BOOL(*NAT_PACKET_CALLBACK)
	(u_long nat_id, u_long agent_id, u_long session_id, NAT_DIRECTION dir, void* packet);

typedef struct {
        NODE                                    node;
	u_long					id;					/* Agent idenitfier, set by NAT */
	char					desc[NAT_AGENT_DESC_LEN];	/* official description */
	char					name[NAT_AGENT_NAME_LEN];	/* name of agent */
	NAT_AGENT_TYPE			type;				/* One of NAT_AGENT_TYPE */
	u_long					flags;				/* See NAT_FLAG_ */
	u_long					events;				/* bit-field of requested callback events */
	u_long					timer_interval;		/* timer event interval (in seconds) */
	NAT_EVENT_CALLBACK		event_callback;		/* agent callback function pointer */
	NAT_SESSION_TAG			session_tag;		/* Identifies type of packets to translate */
	NAT_PACKET_CALLBACK		packet_callback;	/* agent packet processing function */

} NAT_AGENT_INFO;


#ifdef __cplusplus
extern "C" {
#endif

/*****************************************************************************
Function:	natGetID

Description:
This function is called by the external agent to obtain the NAT service 
identifier and its type.  The external agent is responsible 
for allocating the NAT_ID_INFO data structure and pass its pointer as the 
argument to this function.  NAT fills in the structure including the NAT ID.
*****************************************************************************/
NAT_STATUS	natGetID
			(
			NAT_ID_INFO*
			);

/*****************************************************************************
Function:	natRegisterAgent

Description:
This function is called by the external agent to register with the NAT service.  
The external agent allocates the NAT_AGENT_INFO storage and fill in the agent's 
information before passing it to the function.  Upon successful completion of 
this function, NAT will assign and return the agent ID (i.e. handle) in the 
NAT_AGENT_INFO data structure.
*****************************************************************************/
NAT_STATUS	natRegisterAgent
			(
			u_long nat_id, 
			NAT_AGENT_INFO*
			);

/*****************************************************************************
Function:	natUnregisterAgent

Description:
This function is called by the external agent to unregister itself from the 
NAT service.
*****************************************************************************/
NAT_STATUS natUnregisterAgent
			(
			u_long nat_id, 
			u_long agent_id
			);

/*****************************************************************************
Function:	natSetBind

Description:
This function is called by the external agent to create a new address bind or 
set certain parameters of an existing bind.  The bind can be an address bind 
or transport bind.  The caller is expected to fill in the NAT_BIND_INFO 
structure.  A new bind request is made by setting the bind ID (in NAT_BIND_INFO) 
to 0.  A non-zero bind ID would be interpreted to mean that the agent is 
attempting to set some existing bind parameters.

If the caller requests for a bind creation, and NAT is successful in creating 
a new bind, the function will fill the NAT_BIND_INFO structure with the newly 
assigned bind ID.  If the request is for setting some bind parameters and the 
bind ID is valid, it will replace the NAT bind information with the new one.

NOTE:
Currently, only new bind creation is supported.  For request to set existing
bind parameters, the input bind parameters will be copied to the existing bind
entry, but will have no effect on NAT.
*****************************************************************************/
NAT_STATUS	natSetBind
			(
			u_long nat_id, 
			u_long agent_id, 
			NAT_BIND_INFO*
			);

/*****************************************************************************
Function:	natSetSession

Description:
This function is called by the external agent to create a new session or set 
certain parameters of an existing session.  The caller supplies the specifics 
of the parameters either for a new session or for updating an existing session.  
A new session request is made by setting the session ID in the NAT_SESSION_INFO 
to 0, and non-zero for setting the parameters of an existing session.

If the caller requests for a session creation, and NAT is successful in creating 
a new session, NAT will fill the NAT_SESSION_INFO structure with the newly 
assigned session ID.  If the request is for setting some session parameters and 
the session ID is valid, it will replace the NAT session information with the 
new one.

NOTE:
This function in supported in the current release.  It is only partially 
implemented and has no impact on NAT.
*****************************************************************************/
NAT_STATUS	natSetSession
			(
			u_long nat_id, 
			u_long agent_id, 
			NAT_SESSION_INFO*
			);

/*****************************************************************************
Function:	natFreeBind

Description:
This function is called by the external agent to terminate the specified bind 
and any sessions that are based on this bind.
*****************************************************************************/
NAT_STATUS	natFreeBind
			(
			u_long nat_id, 
			u_long agent_id, 
			u_long bind_id
			);

/*****************************************************************************
Function:	natFreeSession

Description:
This function is called by the external agent to terminate the specified session.

NOTE:
This function in supported in the current release.  It is only partially 
implemented and has no impact on NAT.
*****************************************************************************/
NAT_STATUS	natFreeSession
			(
			u_long nat_id, 
			u_long agent_id, 
			u_long session_id
			);

/*****************************************************************************
Function:	natFreeBundle

Description:
This function is called by the external agent to terminate a bundle of sessions 
identified by the same bundle ID.

NOTE:
This function in supported in the current release.  It is only partially 
implemented and has no impact on NAT.
*****************************************************************************/
NAT_STATUS	natFreeBundle
			(
			u_long nat_id, 
			u_long agent_id, 
			u_long bundle_id
			);

/*****************************************************************************
Function:	natGetAddrBind

Description:
This function is called by the external agent to obtain address bind 
information.  The caller may specify both or just the local_addr or the 
global_addr and set the other to zero.  NAT will fill up the NAT_BIND_INFO 
data structure with the address bind information unless it cannot find a match 
for the addresses specified.
*****************************************************************************/
NAT_STATUS	natGetAddrBind
			(
			u_long nat_id, 
			u_long local_addr, 
			u_long global_addr,
			NAT_BIND_INFO*
			);

/*****************************************************************************
Function:	natGetTransportBind

Description:
This function is called by the external agent to obtain the transport ID bind 
information.  The caller may specify both or just one of either local or global 
(address and transport).  The check flag is added give caller the option to 
look for a match of remote address and port, or just the remote address only.
Once, the matching bind is found, NAT will fill up the NAT_BIND_INFO data  
structure with the transport bind information unless it cannot find a match  
for the addresses specified.
*****************************************************************************/
NAT_STATUS	natGetTransportBind
			(
			u_long nat_id, 
			NAT_BIND_SESSION* session,
			NAT_BIND_INFO* bind,
			NAT_BIND_CHECK check
			);

/*****************************************************************************
Function:	natBindShow

Description:
This function is provided for a human user to display all the bind descriptors 
that are currently alive in the list.  It is intended for informational 
purpose only and not for the use by an external agent.
*****************************************************************************/
void		natBindShow (void);

#ifdef __cplusplus
}
#endif

#endif /* Dont' add anything after this line */
